home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / src / mail / pine3.96.tar.gz / pine3.96.tar / pine3.96 / imap / ANSI / c-client / dummyos2.c < prev    next >
C/C++ Source or Header  |  1996-03-15  |  15KB  |  607 lines

  1. /*
  2.  * Program:    Dummy routines for DOS
  3.  *
  4.  * Author:    Mark Crispin
  5.  *        Networks and Distributed Computing
  6.  *        Computing & Communications
  7.  *        University of Washington
  8.  *        Administration Building, AG-44
  9.  *        Seattle, WA  98195
  10.  *        Internet: MRC@CAC.Washington.EDU
  11.  *
  12.  * Date:    24 May 1993
  13.  * Last Edited:    14 March 1996
  14.  *
  15.  * Copyright 1996 by the University of Washington
  16.  *
  17.  *  Permission to use, copy, modify, and distribute this software and its
  18.  * documentation for any purpose and without fee is hereby granted, provided
  19.  * that the above copyright notice appears in all copies and that both the
  20.  * above copyright notice and this permission notice appear in supporting
  21.  * documentation, and that the name of the University of Washington not be
  22.  * used in advertising or publicity pertaining to distribution of the software
  23.  * without specific, written prior permission.  This software is made
  24.  * available "as is", and
  25.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  26.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  27.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  28.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  29.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  30.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  31.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  32.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  33.  *
  34.  */
  35.  
  36.  
  37. #include <ctype.h>
  38. #include <stdio.h>
  39. #include <errno.h>
  40. #include <fcntl.h>
  41. #define INCL_DOS
  42. #include <os2.h>
  43. #undef ADDRESS
  44. #include "mail.h"
  45. #include "osdep.h"
  46. #include <sys/stat.h>
  47. #include <io.h>
  48. #include "dummy.h"
  49. #include "misc.h"
  50.  
  51. long dummy_badname (char *tmp,char *s);
  52.  
  53. /* Dummy routines */
  54.  
  55.  
  56. /* Driver dispatch used by MAIL */
  57.  
  58. DRIVER dummydriver = {
  59.   "dummy",            /* driver name */
  60.   (DRIVER *) NIL,        /* next driver */
  61.   dummy_valid,            /* mailbox is valid for us */
  62.   dummy_parameters,        /* manipulate parameters */
  63.   dummy_find,            /* find mailboxes */
  64.   dummy_find_bboards,        /* find bboards */
  65.   dummy_find_all,        /* find all mailboxes */
  66.   dummy_find_all_bboards,    /* find all bboards */
  67.   dummy_subscribe,        /* subscribe to mailbox */
  68.   dummy_unsubscribe,        /* unsubscribe from mailbox */
  69.   dummy_subscribe_bboard,    /* subscribe to bboard */
  70.   dummy_unsubscribe_bboard,    /* unsubscribe from bboard */
  71.   dummy_create,            /* create mailbox */
  72.   dummy_delete,            /* delete mailbox */
  73.   dummy_rename,            /* rename mailbox */
  74.   dummy_open,            /* open mailbox */
  75.   dummy_close,            /* close mailbox */
  76.   dummy_fetchfast,        /* fetch message "fast" attributes */
  77.   dummy_fetchflags,        /* fetch message flags */
  78.   dummy_fetchstructure,        /* fetch message structure */
  79.   dummy_fetchheader,        /* fetch message header only */
  80.   dummy_fetchtext,        /* fetch message body only */
  81.   dummy_fetchbody,        /* fetch message body section */
  82.   dummy_setflag,        /* set message flag */
  83.   dummy_clearflag,        /* clear message flag */
  84.   dummy_search,            /* search for message based on criteria */
  85.   dummy_ping,            /* ping mailbox to see if still alive */
  86.   dummy_check,            /* check for new messages */
  87.   dummy_expunge,        /* expunge deleted messages */
  88.   dummy_copy,            /* copy messages to another mailbox */
  89.   dummy_move,            /* move messages to another mailbox */
  90.   dummy_append,            /* append string message to mailbox */
  91.   dummy_gc            /* garbage collect stream */
  92. };
  93.  
  94.  
  95.                 /* prototype stream */
  96. MAILSTREAM dummyproto = {&dummydriver};
  97.  
  98.                 /* driver parameters */
  99. static char *file_extension = NIL;
  100.  
  101. /* Dummy validate mailbox
  102.  * Accepts: mailbox name
  103.  * Returns: our driver if name is valid, NIL otherwise
  104.  */
  105.  
  106. DRIVER *dummy_valid (char *name)
  107. {
  108.   char tmp[MAILTMPLEN];
  109.   struct stat sbuf;
  110.                 /* must be valid local mailbox */
  111.   return (name && *name && (*name != '*') && (*name != '{') &&
  112.                 /* INBOX is always accepted */
  113.       ((!strcmp (ucase (strcpy (tmp,name)),"INBOX")) ||
  114.                 /* so is any valid file */
  115.        (mailboxfile (tmp,name) && !stat (tmp,&sbuf))))
  116.     ? &dummydriver : NIL;
  117. }
  118.  
  119.  
  120. /* Dummy manipulate driver parameters
  121.  * Accepts: function code
  122.  *        function-dependent value
  123.  * Returns: function-dependent return value
  124.  */
  125.  
  126. void *dummy_parameters (long function,void *value)
  127. {
  128.   switch ((int) function) {
  129.   case SET_EXTENSION:
  130.     if (file_extension) fs_give ((void **) &file_extension);
  131.     if (*(char *) value) file_extension = cpystr ((char *) value);
  132.     break;
  133.   case GET_EXTENSION:
  134.     value = (void *) file_extension;
  135.     break;
  136.   default:
  137.     value = NIL;        /* error case */
  138.     break;
  139.   }
  140.   return value;
  141. }
  142.  
  143. /* Dummy find list of subscribed mailboxes
  144.  * Accepts: mail stream
  145.  *        pattern to search
  146.  */
  147.  
  148. void dummy_find (MAILSTREAM *stream,char *pat)
  149. {
  150.   void *sdb = NIL;
  151.   char *t = sm_read (&sdb);
  152.   if (t) do if ((*t != '{') && strcmp (t,"INBOX") && pmatch (t,pat))
  153.     mm_mailbox (t);
  154.   while (t = sm_read (&sdb));    /* read subscription database */
  155. }
  156.  
  157.  
  158. /* Dummy find list of subscribed bboards
  159.  * Accepts: mail stream
  160.  *        pattern to search
  161.  */
  162.  
  163. void dummy_find_bboards (MAILSTREAM *stream,char *pat)
  164. {
  165.                 /* return silently */
  166. }
  167.  
  168. /* Dummy find list of all mailboxes
  169.  * Accepts: mail stream
  170.  *        pattern to search
  171.  */
  172.  
  173. void dummy_find_all (MAILSTREAM *stream,char *pat)
  174. {
  175.   ULONG count = 1;
  176.   FILEFINDBUF3 findbuf;
  177.   HDIR hdir = HDIR_CREATE;
  178.   char *s,tmp[MAILTMPLEN],file[MAILTMPLEN];
  179.   int i = 0;
  180.   int doinbox = T;
  181.                 /* directory specified in pattern? */
  182.   if ((s = strrchr (pat,'\\')) || (*(s = pat + 1) == ':')) {
  183.     strncpy (file,pat,i = (++s) - pat);
  184.     file[i] = '\0';        /* tie off prefix */
  185.   }
  186.                 /* make fully-qualified file name */
  187.   if (!mailboxfile (tmp,pat)) return;
  188.                 /* all files in directory */
  189.   strcpy ((s = strrchr (tmp,'\\')) ? s : tmp + 2,"\\*");
  190.   if (file_extension) {
  191.     strcat (s, ".");
  192.     strcat (s, file_extension);
  193.   }
  194.                 /* loop through matching files */
  195.   if (!DosFindFirst (tmp,&hdir,FILE_NORMAL,&findbuf,sizeof (findbuf),&count,
  196.              FIL_STANDARD)) do {
  197.                 /* suppress extension */
  198.     if (file_extension && (s = strchr (findbuf.achName,'.'))) *s = '\0';
  199.                 /* build file name */
  200.     strcpy (file + i,findbuf.achName);
  201.     if (!stricmp (findbuf.achName,"INBOX")) doinbox = 0;
  202.     if (pmatch (file,pat)) mm_mailbox (file);
  203.     count = 1;
  204.   } while (!DosFindNext (hdir,&findbuf,sizeof (findbuf),&count));
  205.                 /* always an INBOX */
  206.   if (doinbox && pmatch ("INBOX",pat)) mm_mailbox ("INBOX");
  207. }
  208.  
  209.  
  210. /* Dummy find list of all bboards
  211.  * Accepts: mail stream
  212.  *        pattern to search
  213.  */
  214.  
  215. void dummy_find_all_bboards (MAILSTREAM *stream,char *pat)
  216. {
  217.                 /* return silently */
  218. }
  219.  
  220. /* Dummy subscribe to mailbox
  221.  * Accepts: mail stream
  222.  *        mailbox to add to subscription list
  223.  * Returns: T on success, NIL on failure
  224.  */
  225.  
  226. long dummy_subscribe (MAILSTREAM *stream,char *mailbox)
  227. {
  228.   char tmp[MAILTMPLEN];
  229.   if (mailboxfile (tmp,mailbox)) return sm_subscribe (mailbox);
  230.   else return dummy_badname (tmp,mailbox);
  231. }
  232.  
  233.  
  234. /* Dummy unsubscribe to mailbox
  235.  * Accepts: mail stream
  236.  *        mailbox to delete from subscription list
  237.  * Returns: T on success, NIL on failure
  238.  */
  239.  
  240. long dummy_unsubscribe (MAILSTREAM *stream,char *mailbox)
  241. {
  242.   char tmp[MAILTMPLEN];
  243.   if (mailboxfile (tmp,mailbox)) return sm_unsubscribe (mailbox);
  244.   else return dummy_badname (tmp,mailbox);
  245. }
  246.  
  247.  
  248. /* Dummy subscribe to bboard
  249.  * Accepts: mail stream
  250.  *        bboard to add to subscription list
  251.  * Returns: T on success, NIL on failure
  252.  */
  253.  
  254. long dummy_subscribe_bboard (MAILSTREAM *stream,char *mailbox)
  255. {
  256.   return NIL;            /* always fails */
  257. }
  258.  
  259.  
  260. /* Dummy unsubscribe to bboard
  261.  * Accepts: mail stream
  262.  *        bboard to delete from subscription list
  263.  * Returns: T on success, NIL on failure
  264.  */
  265.  
  266. long dummy_unsubscribe_bboard (MAILSTREAM *stream,char *mailbox)
  267. {
  268.   return NIL;            /* always fails */
  269. }
  270.  
  271. /* Dummy create mailbox
  272.  * Accepts: mail stream
  273.  *        mailbox name to create
  274.  *        driver type to use
  275.  * Returns: T on success, NIL on failure
  276.  */
  277.  
  278. long dummy_create (MAILSTREAM *stream,char *mailbox)
  279. {
  280.   char tmp[MAILTMPLEN];
  281.   int fd;
  282.   if (!mailboxfile (tmp,mailbox)) return dummy_badname (tmp,mailbox);
  283.   if ((fd = open (tmp,O_WRONLY|O_CREAT|O_EXCL,S_IREAD|S_IWRITE)) < 0) {
  284.                 /* failed */
  285.     sprintf (tmp,"Can't create mailbox %s: %s",mailbox,strerror (errno));
  286.     mm_log (tmp,ERROR);
  287.     return NIL;
  288.   }
  289.   close (fd);            /* close the file */
  290.   return LONGT;            /* return success */
  291. }
  292.  
  293.  
  294. /* Dummy delete mailbox
  295.  * Accepts: mail stream
  296.  *        mailbox name to delete
  297.  * Returns: T on success, NIL on failure
  298.  */
  299.  
  300. long dummy_delete (MAILSTREAM *stream,char *mailbox)
  301. {
  302.   return dummy_rename (stream,mailbox,NIL);
  303. }
  304.  
  305.  
  306. /* Mail rename mailbox
  307.  * Accepts: mail stream
  308.  *        old mailbox name
  309.  *        new mailbox name
  310.  * Returns: T on success, NIL on failure
  311.  */
  312.  
  313. long dummy_rename (MAILSTREAM *stream,char *old,char *new)
  314. {
  315.   char tmp[MAILTMPLEN],file[MAILTMPLEN],lock[MAILTMPLEN],lockx[MAILTMPLEN];
  316.                 /* make file name */
  317.   if (!mailboxfile (file,old)) return dummy_badname (tmp,old);
  318.   if (new && !mailboxfile (tmp,new)) return dummy_badname (tmp,new);
  319.                 /* do the rename or delete operation */
  320.   if (new ? rename (file,tmp) : unlink (file)) {
  321.     sprintf (tmp,"Can't %s mailbox %s: %s",new ? "rename" : "delete",old,
  322.          strerror (errno));
  323.     mm_log (tmp,ERROR);
  324.     return NIL;
  325.   }
  326.   return LONGT;            /* return success */
  327. }
  328.  
  329. /* Dummy open
  330.  * Accepts: stream to open
  331.  * Returns: stream on success, NIL on failure
  332.  */
  333.  
  334. MAILSTREAM *dummy_open (MAILSTREAM *stream)
  335. {
  336.   char tmp[MAILTMPLEN];
  337.   struct stat sbuf;
  338.   int fd = -1;
  339.                 /* OP_PROTOTYPE call or silence */
  340.   if (!stream || stream->silent) return NIL;
  341.   if (strcmp (ucase (strcpy (tmp,stream->mailbox)),"INBOX") &&
  342.       ((fd = open (mailboxfile (tmp,stream->mailbox),O_RDONLY,NIL)) < 0))
  343.     sprintf (tmp,"%s: %s",strerror (errno),stream->mailbox);
  344.   else {
  345.     if (fd >= 0) {        /* if got a file */
  346.       fstat (fd,&sbuf);        /* sniff at its size */
  347.       close (fd);
  348.       if (sbuf.st_size) sprintf (tmp,"Not a mailbox: %s",stream->mailbox);
  349.       else fd = -1;        /* a-OK */
  350.     }
  351.     if (fd < 0) {        /* no file, right? */
  352.       if (!stream->silent) {    /* only if silence not requested */
  353.                 /* say there are 0 messages */
  354.     mail_exists (stream,(long) 0);
  355.     mail_recent (stream,(long) 0);
  356.       }
  357.       return stream;        /* return success */
  358.     }
  359.   }
  360.   if (!stream->silent) mm_log (tmp,ERROR);
  361.   return NIL;            /* always fails */
  362. }
  363.  
  364.  
  365. /* Dummy close
  366.  * Accepts: MAIL stream
  367.  */
  368.  
  369. void dummy_close (MAILSTREAM *stream)
  370. {
  371.                 /* return silently */
  372. }
  373.  
  374. /* Dummy fetch fast information
  375.  * Accepts: MAIL stream
  376.  *        sequence
  377.  */
  378.  
  379. void dummy_fetchfast (MAILSTREAM *stream,char *sequence)
  380. {
  381.   fatal ("Impossible dummy_fetchfast");
  382. }
  383.  
  384.  
  385. /* Dummy fetch flags
  386.  * Accepts: MAIL stream
  387.  *        sequence
  388.  */
  389.  
  390. void dummy_fetchflags (MAILSTREAM *stream,char *sequence)
  391. {
  392.   fatal ("Impossible dummy_fetchflags");
  393. }
  394.  
  395.  
  396. /* Dummy fetch envelope
  397.  * Accepts: MAIL stream
  398.  *        message # to fetch
  399.  *        pointer to return body
  400.  * Returns: envelope of this message, body returned in body value
  401.  */
  402.  
  403. ENVELOPE *dummy_fetchstructure (MAILSTREAM *stream,long msgno,BODY **body)
  404. {
  405.   fatal ("Impossible dummy_fetchstructure");
  406.   return NIL;
  407. }
  408.  
  409.  
  410. /* Dummy fetch message header
  411.  * Accepts: MAIL stream
  412.  *        message # to fetch
  413.  * Returns: message header in RFC822 format
  414.  */
  415.  
  416. char *dummy_fetchheader (MAILSTREAM *stream,long msgno)
  417. {
  418.   fatal ("Impossible dummy_fetchheader");
  419.   return NIL;
  420. }
  421.  
  422. /* Dummy fetch message text (body only)
  423.  * Accepts: MAIL stream
  424.  *        message # to fetch
  425.  * Returns: message text in RFC822 format
  426.  */
  427.  
  428. char *dummy_fetchtext (MAILSTREAM *stream,long msgno)
  429. {
  430.   fatal ("Impossible dummy_fetchtext");
  431.   return NIL;
  432. }
  433.  
  434.  
  435. /* Berkeley fetch message body as a structure
  436.  * Accepts: Mail stream
  437.  *        message # to fetch
  438.  *        section specifier
  439.  * Returns: pointer to section of message body
  440.  */
  441.  
  442. char *dummy_fetchbody (MAILSTREAM *stream,long m,char *sec,unsigned long *len)
  443. {
  444.   fatal ("Impossible dummy_fetchbody");
  445.   return NIL;
  446. }
  447.  
  448.  
  449. /* Dummy set flag
  450.  * Accepts: MAIL stream
  451.  *        sequence
  452.  *        flag(s)
  453.  */
  454.  
  455. void dummy_setflag (MAILSTREAM *stream,char *sequence,char *flag)
  456. {
  457.   fatal ("Impossible dummy_setflag");
  458. }
  459.  
  460.  
  461. /* Dummy clear flag
  462.  * Accepts: MAIL stream
  463.  *        sequence
  464.  *        flag(s)
  465.  */
  466.  
  467. void dummy_clearflag (MAILSTREAM *stream,char *sequence,char *flag)
  468. {
  469.   fatal ("Impossible dummy_clearflag");
  470. }
  471.  
  472.  
  473. /* Dummy search for messages
  474.  * Accepts: MAIL stream
  475.  *        search criteria
  476.  */
  477.  
  478. void dummy_search (MAILSTREAM *stream,char *criteria)
  479. {
  480.                 /* return silently */
  481. }
  482.  
  483. /* Dummy ping mailbox
  484.  * Accepts: MAIL stream
  485.  * Returns: T if stream alive, else NIL
  486.  * No-op for readonly files, since read/writer can expunge it from under us!
  487.  */
  488.  
  489. long dummy_ping (MAILSTREAM *stream)
  490. {
  491.   char tmp[MAILTMPLEN];
  492.   MAILSTREAM *test = mail_open (NIL,stream->mailbox,OP_PROTOTYPE);
  493.                 /* swap streams if looks like a new driver */
  494.   if (test && (test->dtb != stream->dtb))
  495.     test = mail_open (stream,strcpy (tmp,stream->mailbox),NIL);
  496.   return test ? T : NIL;
  497. }
  498.  
  499.  
  500. /* Dummy check mailbox
  501.  * Accepts: MAIL stream
  502.  * No-op for readonly files, since read/writer can expunge it from under us!
  503.  */
  504.  
  505. void dummy_check (MAILSTREAM *stream)
  506. {
  507.   dummy_ping (stream);        /* invoke ping */
  508. }
  509.  
  510.  
  511. /* Dummy expunge mailbox
  512.  * Accepts: MAIL stream
  513.  */
  514.  
  515. void dummy_expunge (MAILSTREAM *stream)
  516. {
  517.                 /* return silently */
  518. }
  519.  
  520. /* Dummy copy message(s)
  521.  * Accepts: MAIL stream
  522.  *        sequence
  523.  *        destination mailbox
  524.  * Returns: T if copy successful, else NIL
  525.  */
  526.  
  527. long dummy_copy (MAILSTREAM *stream,char *sequence,char *mailbox)
  528. {
  529.   fatal ("Impossible dummy_copy");
  530.   return NIL;
  531. }
  532.  
  533.  
  534. /* Dummy move message(s)
  535.  * Accepts: MAIL stream
  536.  *        sequence
  537.  *        destination mailbox
  538.  * Returns: T if move successful, else NIL
  539.  */
  540.  
  541. long dummy_move (MAILSTREAM *stream,char *sequence,char *mailbox)
  542. {
  543.   fatal ("Impossible dummy_move");
  544.   return NIL;
  545. }
  546.  
  547. /* Dummy append message string
  548.  * Accepts: mail stream
  549.  *        destination mailbox
  550.  *        stringstruct of message to append
  551.  * Returns: T on success, NIL on failure
  552.  */
  553.  
  554. long dummy_append (MAILSTREAM *stream,char *mailbox,char *flags,char *date,
  555.            STRING *message)
  556. {
  557.   struct stat sbuf;
  558.   int fd = -1;
  559.   int e;
  560.   char tmp[MAILTMPLEN];
  561.   if ((strcmp (ucase (strcpy (tmp,mailbox)),"INBOX")) &&
  562.        ((fd = open (mailboxfile (tmp,mailbox),O_RDONLY,NIL)) < 0)) {
  563.     if ((e = errno) == ENOENT) {/* failed, was it no such file? */
  564.       mm_notify (stream,"[TRYCREATE] Must create mailbox before append",
  565.          (long) NIL);
  566.       return NIL;
  567.     }
  568.     sprintf (tmp,"%s: %s",strerror (e),mailbox);
  569.     mm_log (tmp,ERROR);        /* pass up error */
  570.     return NIL;            /* always fails */
  571.   }
  572.   else if (fd >= 0) {        /* found file? */
  573.     fstat (fd,&sbuf);        /* get its size */
  574.     close (fd);            /* toss out the fd */
  575.     if (sbuf.st_size) {        /* non-empty file? */
  576.       sprintf (tmp,"Indeterminate mailbox format: %s",mailbox);
  577.       mm_log (tmp,ERROR);
  578.       return NIL;
  579.     }
  580.   }
  581.   return (*default_proto ()->dtb->append) (stream,mailbox,flags,date,message);
  582. }
  583.  
  584.  
  585. /* Dummy garbage collect stream
  586.  * Accepts: mail stream
  587.  *        garbage collection flags
  588.  */
  589.  
  590. void dummy_gc (MAILSTREAM *stream,long gcflags)
  591. {
  592.                 /* return silently */
  593. }
  594.  
  595. /* Return bad file name error message
  596.  * Accepts: temporary buffer
  597.  *        file name
  598.  * Returns: long NIL always
  599.  */
  600.  
  601. long dummy_badname (char *tmp,char *s)
  602. {
  603.   sprintf (tmp,"Invalid mailbox name: %s",s);
  604.   mm_log (tmp,ERROR);
  605.   return (long) NIL;
  606. }
  607.